#include <cstdint>
#include <iostream>
#include <cstdio>
#include "testFrame.h"
using namespace std;

LD_SYMBOL_ALIGN(__stest_init, InitInfo_t);
LD_SYMBOL_ALIGN(__etest_init, InitInfo_t);

LD_SYMBOL_ALIGN(__stest_run, RunInfo_t);
LD_SYMBOL_ALIGN(__etest_run, RunInfo_t);

int main(int argc, char** argv)
{
    INFO("Start Test");
    pInitInfo_t initInfo = NULL;
    pRunInfo_t runInfo = NULL;
    try
    {
        INFO("Start Initial");
        for (initInfo = __stest_init; initInfo < __etest_init; initInfo++)
            initInfo->cb();
        INFO("Test Cases Init Done");
    }
    catch (const std::exception& e)
    {
        ERROR("Catch Standard Exception : %s In %s", e.what(), initInfo->name);
        INFO("End Test");
        return -1;
    }
    catch (...)
    {
        ERROR("Catch Unknow Exception In %s", initInfo->name);
        INFO("End Test");
        return -2;
    }

    int Res[2] = { 0 };
    try
    {
        INFO("Start Run TestCases");

        for (runInfo = __stest_run; runInfo < __etest_run; runInfo++)
        {
            auto res = runInfo->cb();
            Res[res]++;
            INFO("Test Item -> [%s]: %s", runInfo->name, res ? "Passed" : "Failed");
        }

        INFO("Test Done");
        INFO("All Test Point(s): %llu", ((size_t) __etest_run - (size_t) __stest_run) / sizeof(RunInfo_t));
        INFO("%d Point(s) Passed, %d Point(s) Failed", Res[1], Res[0]);

    }
    catch (const std::exception& e)
    {
        ERROR("Catch Standard Exception: %s In %s", e.what(), runInfo->name);
        INFO("End Test");
        return -1;
    }
    catch (...)
    {
        ERROR("Catch Unknow Exception In %s", runInfo->name);
        INFO("End Test");
        return -2;
    }

    return 0;
}
